<?php

namespace app\admin\service;

use app\api\service\CommonService;
use app\model\AgentSmsLog;
use app\model\SmsModule;
use think\Collection;
use think\facade\Db;

class AgentSmsSevice extends CommonService
{
    /*
     根据模板 列表发送短息给代理商
    */
    public function moduleSend(Collection $moduleList)
    {
        set_time_limit(0);
        ignore_user_abort(true);
        if ($moduleList->isEmpty()) {
            return $this->valiReturn();
        }

        $dateTime = date('Y-m-d H:i:s');
        $maxCount = 5000; // 手机号单次最多数量
        $idArr = $moduleList->column('id');
        Db::startTrans();
        try {
            $moduleList = SmsModule::lock(true)->whereIn('id', $idArr)->select(); // 锁表
            if ($moduleList->isEmpty()) {
                Db::rollback();

                return $this->inValiReturn('没有待发送短信');
            }

            // step   更新【 尚未执行过】的模板的执行时间
            $res = SmsModule::whereIn('id', $idArr)->whereNull('handle_time')->update(['handle_time' => $dateTime]);

            // step  更新 【还没发送成功】代理商对应的手机号
            $res = AgentSmsLog::withJoin('agent')->whereIn('module_id', $idArr)->where('agent_sms_log.status', '<>', 1)->update(['agent_sms_log.mobile' => Db::raw('agent.mobile')]);

            // step  循环模板 ，发送短信给对应模板下 代理商
            foreach ($moduleList as $k => $v) {
                $id = 0;  // 下面while 循环里面 根据 id 去查询
                $maxLoop = 10; //限制单个模板发送次数
                $loop = 0;

                // step  由于短信限制手机号5000个 需要while 去循环发送
                while (1) {
                    $mobileList = AgentSmsLog::where('module_id', $v->id)
                                ->where('status', '<>', 1)->where('mobile', '<>', '')->where('id', '>', $id)
                                ->limit($maxCount)->order('id', 'asc')
                                ->field('id,mobile')
                                ->select();

                    if ($mobileList->isEmpty()) {
                        break;
                    }

                    $mobileArr = array_unique($mobileList->column('mobile'));
                    if (!$mobileArr) {
                        break;
                    }

                    $logIdArr = $mobileList->column('id'); // 提取 短信发送的id 用于更新
                    $id = $logIdArr[count($logIdArr) - 1]; // 去除最后一个id 用户查询 mobileList == 否则一直发送失败的话会一直循环

                    // 发送短信 == 发送失败尝试再发2次
                    for($i=0;$i<3;$i++){
                        $res = sendSms($v->content, $mobileArr);
                        if ($res['code']) {
                            doLog('批量发送短信失败，'.$res['msg']);
                        }else{
                            break;
                        }
                    }
                    $updateArr = ['msgid' => $res['data']['msgid'], 'send_time' => $dateTime, 'status' => 1];
                    if ($res['code']) {
                        doLog('批量发送短信失败，'.$res['msg']);
                        $updateArr['status'] = 2;
                    }

                    // 更新实际短信发送记录和发送状态
                    AgentSmsLog::whereIn('id', $logIdArr)->where('status', '<>', 1)->where('mobile', '<>', '')->update($updateArr);

                    ++$loop;
                    if ($loop > $maxLoop) {
                        break;
                    }
                }
            }

            Db::commit();

            return $this->valiReturn();
        } catch (\Exception $e) {
            Db::rollback();
            doWarning(getExceptionMsg($e));

            return $this->valiReturn(getExceptionMsg($e));
        }
    }
}
